home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 17
/
CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso
/
CUCD
/
Programming
/
DiceSource
/
src
/
dd
/
dbug.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-09-09
|
14KB
|
492 lines
/*
* (c)Copyright 1992-1997 Obvious Implementations Corp. Redistribution and
* use is allowed under the terms of the DICE-LICENSE FILE,
* DICE-LICENSE.TXT.
*/
#include "defs.h"
#include "dbug_protos.h"
#define EXECBASE (*(struct ExecBase **)4)
//#define THISPROC ((struct Process *)(EXECBASE->ThisTask))
#define THISPROC ((struct Process *)(SysBase->ThisTask))
// ************************************************************************
Prototype void Newline(void);
Prototype void PrintAddress(ULONG addr);
Prototype void OffsetAddressBuf(ULONG addr, char *buf);
Prototype void InitCommand(void);
Prototype void InitModes(void);
Prototype void RefreshCommand(int fullRefresh);
Prototype void RefreshPrompt(BOOL fullRefresh);
Prototype void RefreshWindow(int fullRefresh);
Prototype void RefreshAllWindows(int fullRefresh);
Prototype void SetDisplayMode(WORD, BOOL);
Prototype void ReadPrefs(void);
Prototype void WritePrefs(void);
Prototype void abort(void);
Prototype BOOL ParseArgToken(char *buf);
Prototype ULONG OnOffToggle(char *arg, ULONG val, ULONG mask);
Prototype int main(int ac, char *av[]);
Prototype LONG CalcDisplayLines(void);
Prototype void SetModeSave(WORD mode);
Prototype ULONG ValidMemCheck(ULONG address);
Prototype __stkargs void kprintf(unsigned char *arg, ...);
// ***********************************************************************
Prototype UBYTE LineBuf[128];
Prototype UBYTE DirBuf[128];
Prototype WORD ForceFullRefresh;
Prototype UBYTE RexxReplyString[MAX_REXX_REPLY];
Prototype UBYTE DefaultPubName[128];
Prototype char lastCommand[128];
Prototype int RStepFlag;
Prototype char rexxhostname[16];
// ************************************************************************
DPREFS dprefs = { 0,0,640,200 };
ULONG ModeTopSave[MAX_MODES];
ULONG ModeSubSave[MAX_MODES];
LONG CommonAddrTable[MAX_MODES];
UBYTE LineBuf[128];
UBYTE DefaultPubName[128];
WORD ForceFullRefresh;
char targetName[128];
__aligned char exeCommandName[128]; // cli_CommandName of debugged program
char lastCommand[128];
char commandLine[128];
UBYTE RexxReplyString[MAX_REXX_REPLY];
UBYTE DirBuf[128];
// UWORD commandCol = 0, commandEnd = 0;
UWORD commandCol = 0;
UWORD commandEnd = 0;
int RStepFlag = 0;
// ************************************************************************
void Newline(void) {
ScrEOL();
ScrPlain();
ScrPutNewline();
ScrFlush();
}
void PrintAddress(ULONG addr) {
if (CurDisplay->ds_DisplayOffsets) {
char *s = NearestValue(addr);
if (s) {
ULONG val;
LookupSymbol(s, &val);
ScrPrintf("%s + $%04X\t", s, addr - val);
return;
}
}
ScrPrintf("$%08X ", addr);
}
void OffsetAddressBuf(ULONG addr, char *buf)
{
char *s = NearestValue(addr);
if (s) {
ULONG val;
LookupSymbol(s, &val);
sprintf(buf, "%s+%04x", s, addr - val);
} else {
sprintf(buf, "%08x", addr);
}
}
void RefreshPrompt(BOOL fullRefresh) {
DEBUG *debug = FindNearestDebug(CurDisplay->ds_WindowTop);
char *s = debug ? debug->sourceName : "NO SOURCE";
int len = CurDisplay->ds_PromptStart+1;
ScrPlain(); // put line back to normal
ScrRowCol(CurDisplay->ds_ScrRows-2, len);
CurDisplay->ds_PromptLen = ScrPrintf("(%s): ", s) + len;
}
// ************************************************************************
void InitCommand(void) {
if(stricmp(commandLine,"again"))strcpy(lastCommand, commandLine);
strcpy(commandLine, "");
commandCol = commandEnd = 0;
}
void InitModes(void) {
WORD i;
// Initialize the topWindow save array for the various display
// modes to -1
//
// Initialize the CommonAddrTable[] such that the dism/source/mixed
// modes share a common topWindow save address and the hex display
// modes share a common topWinodw save address
for (i = 0; i < MAX_MODES; ++i) {
ModeTopSave[i] = -1;
ModeSubSave[i] = 0;
CommonAddrTable[i] = i;
}
CommonAddrTable[DISPLAY_SOURCE] = DISPLAY_DISM;
CommonAddrTable[DISPLAY_MIXED] = DISPLAY_DISM;
CommonAddrTable[DISPLAY_WORDS] = DISPLAY_BYTES;
CommonAddrTable[DISPLAY_LONGS] = DISPLAY_BYTES;
ModeTopSave[DISPLAY_HUNKS] = 0;
ModeTopSave[DISPLAY_BREAK] = 0;
ModeTopSave[DISPLAY_SYMBOL] = 0;
ModeTopSave[DISPLAY_HELP] = 0;
}
void RefreshCommand(int fullRefresh) {
DBugDisp *disp = CurDisplay;
ScrRowCol(CurDisplay->ds_ScrRows-2, disp->ds_PromptLen);
commandLine[commandEnd] = '\0';
ScrPlain();
ScrPuts(commandLine);
ScrEOL();
ScrRowCol(CurDisplay->ds_ScrRows-2, commandCol+disp->ds_PromptLen);
if(fullRefresh)ScrFlush();
if(fullRefresh == -1)drawdoublebox(); // redraw box if screen was cleared
}
// ************************************************************************
void SetDisplayMode(WORD mode, BOOL setPrefered) {
ULONG addr;
SHORT displayMode = CurDisplay->ds_DisplayMode;
if (setPrefered) {
CurDisplay->ds_PreferedMode = mode;
}
if (displayMode != mode) {
ModeTopSave[CommonAddrTable[displayMode]] = CurDisplay->ds_WindowTop;
ModeSubSave[CommonAddrTable[displayMode]] = CurDisplay->ds_WindowTopLine;
CurDisplay->ds_DisplayMode = displayMode = mode;
if ((addr = ModeTopSave[CommonAddrTable[mode]]) != (ULONG)-1)
CurDisplay->ds_WindowTop = addr;
CurDisplay->ds_WindowTopLine = ModeSubSave[CommonAddrTable[mode]];
}
// if the register command hasn't been used, stay in auto mode
if(!CurDisplay->ds_RegTouched) {
if((mode == DISPLAY_MIXED) || (mode == DISPLAY_DISM))
CurDisplay->ds_RegFlag = 1;
else CurDisplay->ds_RegFlag = 0;
}
}
void SetModeSave(WORD mode) {
ModeTopSave[CommonAddrTable[mode]] = CurDisplay->ds_WindowTop;
ModeSubSave[CommonAddrTable[mode]] = CurDisplay->ds_WindowTopLine;
}
// ************************************************************************
void RefreshAllWindows(int fullRefresh)
{
DBugDisp *disp, *odisp = CurDisplay;
RefreshWindow(fullRefresh); // do current display first
// (its the focus of attention)
for (disp = (DBugDisp *)DisplayList.lh_Head; disp->ds_Node.ln_Succ; disp = (DBugDisp *)disp->ds_Node.ln_Succ) {
if(disp != odisp) { // do not do original window again
CurDisplay = disp;
RefreshWindow(fullRefresh);
}
}
CurDisplay = odisp;
}
// ************************************************************************
void RefreshWindow(int fullRefresh) {
WORD lines, count;
DBugDisp *disp = CurDisplay;
int clearStatus = fullRefresh;
fullRefresh = (fullRefresh) ? 1 : 0;
// check for force or mode change
if ((disp->ds_LastRefreshMode != disp->ds_DisplayMode) || (disp->ds_LastRefreshTop != disp->ds_WindowTop) || ForceFullRefresh ) {
fullRefresh = 1;
ForceFullRefresh = 0;
}
disp->ds_LastRefreshMode = disp->ds_DisplayMode;
disp->ds_LastRefreshTop = disp->ds_WindowTop;
GetWindowSize();
lines = disp->ds_ScrRows - 1;
ScrCursoff();
disp->ds_ScrTop = disp->ds_RegFlag; // 0 for no registers, 1 otherwise
if (clearStatus == -1)ScrClr();
else if (fullRefresh)ScrScrollClr();
ScrHome();
count = RefreshRegisters(lines, (BOOL)fullRefresh);
lines -= count;
disp->ds_ScrTop += count;
lines -= 3; /* command line and two control lines */
if (lines > 0 && programState != STATE_EXITED) {
count = RefreshWatchpoints(lines, (BOOL)fullRefresh);
lines -= count;
disp->ds_ScrTop += count;
}
if (lines > 0) {
if (programState == STATE_EXITED && disp->ds_DisplayMode <= DISPLAY_MIXED) {
ScrPrintf("*** Program exited code %d", programD0);
}
else {
switch (disp->ds_DisplayMode) {
case DISPLAY_DISM: lines -= RefreshDism(lines, (BOOL)fullRefresh); break;
case DISPLAY_SOURCE: lines -= RefreshMixed(lines, (BOOL)fullRefresh, disp->ds_WindowTop, disp->ds_WindowTopLine, 0); break;
case DISPLAY_MIXED: lines -= RefreshMixed(lines, (BOOL)fullRefresh, disp->ds_WindowTop, disp->ds_WindowTopLine, 1); break;
case DISPLAY_BYTES: lines -= RefreshBytes(lines, (BOOL)fullRefresh, disp->ds_WindowTop); break;
case DISPLAY_WORDS: lines -= RefreshWords(lines, (BOOL)fullRefresh, disp->ds_WindowTop); break;
case DISPLAY_LONGS: lines -= RefreshLongs(lines, (BOOL)fullRefresh, disp->ds_WindowTop); break;
case DISPLAY_HUNKS: lines -= RefreshHunks(lines, (BOOL)fullRefresh, disp->ds_WindowTop); break;
case DISPLAY_BREAK: lines -= RefreshBreakpoints(lines, (BOOL)fullRefresh); break;
case DISPLAY_HELP: lines -= RefreshHelp(lines, (BOOL)fullRefresh, disp->ds_WindowTop); break;
case DISPLAY_SYMBOL: lines -= RefreshSymbols(lines, (BOOL)fullRefresh, disp->ds_WindowTop); break;
case DISPLAY_DOSBASE:
case DISPLAY_PROCESS:
case DISPLAY_INFO:
case DISPLAY_EXECBASE:
case DISPLAY_RESOURCES:
case DISPLAY_INTRS:
case DISPLAY_PORTS:
case DISPLAY_TASKS:
case DISPLAY_LIBS:
case DISPLAY_DEVICES:
case DISPLAY_MEMLIST:
case DISPLAY_REXXLIST:
case DISPLAY_SYMLIST:
lines -= RefreshList(lines, (BOOL)fullRefresh, disp->ds_WindowTop); break;
default: break;
}
}
}
while (lines > 0) {
Newline();
lines--;
}
RefreshFKeys(clearStatus);
RefreshPrompt(clearStatus);
RefreshCommand(clearStatus);
ScrCurson();
disp->ds_LastRefreshMode = disp->ds_DisplayMode;
}
/* utility routine to calculate the number of available lines in the display */
LONG CalcDisplayLines(void)
{
LONG lines = CurDisplay->ds_ScrRows - 1;
WORD regcount = 0;
GetWindowSize();
ScrHome();
// subtract register display, command line, and two control lines
// to find how many lines we should look back
// note: no register display normally in source mode
if(CurDisplay->ds_RegFlag)regcount = (lines > 5) ? 5 : lines;
lines = CurDisplay->ds_ScrRows - 6 - regcount;
return(lines);
}
// ************************************************************************
void ReadPrefs(void) {
int fd, i;
APTR wp = THISPROC->pr_WindowPtr;
// turn off requesters
THISPROC->pr_WindowPtr = (APTR)-1;
if((fd = open("dcc_config:dd.config", O_READ)) <= 0) {
fd = open("dcc:config/dd.config", O_READ);
}
for(i=0; i<MAXCOMMAND; i++)dprefs.alias[i]=0; // clear entire alias table
if (fd == -1) {
dprefs.top = dprefs.left = 0;
dprefs.width = 640; dprefs.height = 200;
dprefs.DefaultOffset = 0;
dprefs.DefaultMode = DISPLAY_SOURCE;
}
else {
read(fd, &dprefs, sizeof(DPREFS));
close(fd);
}
THISPROC->pr_WindowPtr = wp;
}
void WritePrefs(void) {
int fd;
APTR wp = THISPROC->pr_WindowPtr;
// turn off requesters
THISPROC->pr_WindowPtr = (APTR)-1;
if((fd = open("dcc_config:dd.config", O_WRITE)) <= 0) {
fd = open("dcc:config/dd.config", O_WRITE);
}
if (fd != -1) {
dprefs.DefaultOffset = CurDisplay->ds_DisplayOffsets;
dprefs.DefaultMode = CurDisplay->ds_DisplayMode;
write(fd, &dprefs, sizeof(DPREFS));
close(fd);
}
THISPROC->pr_WindowPtr = wp;
}
// ************************************************************************
void abort(void) {
CleanMem();
}
BOOL ParseArgToken(char *buf) {
char *b = buf;
while (argSize > 0 && *args == ' ') {
args++;
argSize--;
}
if (*args == '"') {
args++;
argSize--;
while (argSize > 0 && *args != '"' && *args != '\n') {
*buf++ = *args++;
argSize--;
}
if (argSize > 0 && *args == '"') {
args++;
argSize--;
}
}
else {
while (argSize > 0 && *args != ' ' && *args != '\n') {
*buf++ = *args++;
argSize--;
}
}
*buf = '\0';
return (b != buf);
}
char *RexxHostName = NULL; //REXXPORTNAME;
char rexxhostname[16];
int main(int ac, char *av[]) {
int i=1;
atexit(abort);
InitConsole();
if (RexxSysBase == NULL) {
puts("Unable to open rexxsyslib.library.");
exit(20);
}
// port name kludge
{
int num = CreateDiceRexxPort(NULL,REXXPORTNAME);
sprintf(rexxhostname,"%s.%02d",REXXPORTNAME,num);
}
if (!ParseArgToken(targetName)) {
printf("Usage: DBug <options> program [program_args...]\n");
printf("; Before using DBug, compile program with -d1 to add symbols\n");
exit(20);
}
{
WORD i;
char *ps = &targetName[0], *pd = (char *)&exeCommandName[1];
for (i=0; i<128; i++) exeCommandName[i] = 0;
while(*pd++ = *ps++)exeCommandName[0]++;
}
InitModes();
InitCommand();
InitBreakpoints();
memset(DirBuf,0,128);
init_function_keys();
if(((struct Library *)SysBase)->lib_Version >= 36) {
GetCurrentDirName(DirBuf,128);
}
ReadPrefs();
if (!DBugLoadSeg(targetName)) {
printf("Can't loadseg %s\n", targetName);
exit(20);
}
ScrOpen(TRUE, FALSE, NULL);
SymbolCount = CountSymbols();
ResetTarget();
CmdRexx("ddinit.dd"); // check for init file
EnterDebugger();
CmdQuit("");
return 0;
}
ULONG OnOffToggle(char *arg, ULONG val, ULONG mask) {
if (strnicmp(arg, "on", 2) == 0) {
return(val | mask);
} else if (strnicmp(arg, "off", 3) == 0) {
return(val & ~mask);
} else {
return(val ^ mask);
}
}
// This routine checks if it is being fed a legal address for debugger
// access to avoid annoying enforcer.
// All display refresh routines should use it, as well as special
// commands like SET
//
ULONG ValidMemCheck(ULONG address) {
// low memory check (enforcer) first
// might need an 040 specific test if 040 enforcer protects more
if(address < 0x1000)return 0;
// this and should only be done on the 68000
if(address & 1)address &= 0xFFFFFFFE;
// add credit card && CDTV card && ZKick
// if (OpenResource("card.resource")) 00600000 +00550002
// if (FindResident("cdstrap")) 0x00E00000 + 00080000
// if ((((ULONG)(SysBase->LibNode.lib_Node.ln_Name)) >> 16) == 0x20) 0x00200000,0x00080000
if( TypeOfMem((UBYTE *)address) ||
(address >= 0x00F00000 && address <= 0x00FFFFFF) ||
(address >= 0x00BC0000 && address <= 0x00BEFFFF) ||
(address >= 0x00D80000 && address <= 0x00DFFFFF))return address;
return 0;
}